from datetime import datetime
from bson import ObjectId
from typing import Dict, List, Optional, Any
import logging

logger = logging.getLogger(__name__)

class BaseModel:
    """基础模型类，提供通用的数据操作方法"""
    
    def __init__(self, db_collection):
        self.collection = db_collection
    
    def to_dict(self, document: Dict) -> Dict:
        """将MongoDB文档转换为字典，处理ObjectId"""
        if not document:
            return {}
        
        result = {}
        for key, value in document.items():
            if key == '_id':
                result['id'] = str(value)
            elif isinstance(value, ObjectId):
                result[key] = str(value)
            elif isinstance(value, datetime):
                result[key] = value.isoformat()
            else:
                result[key] = value
        
        return result
    
    def validate_object_id(self, obj_id: str) -> bool:
        """验证ObjectId格式"""
        return ObjectId.is_valid(obj_id)
    
    def get_current_timestamp(self) -> datetime:
        """获取当前时间戳"""
        return datetime.now()

class RequirementModel(BaseModel):
    """需求表单模型"""
    
    # 必填字段
    REQUIRED_FIELDS = ['core_goal', 'target_audience', 'budget_per_person', 'focus_point', 'customer_preference', 'customer_pain_points']
    
    # 可选字段
    OPTIONAL_FIELDS = [
        'gift_preference', 'specific_product'
    ]
    
    # 状态选项
    STATUS_OPTIONS = ['draft', 'in_progress', 'completed']
    
    def __init__(self, db):
        super().__init__(db.requirements)
        self.db = db
    
    def validate_data(self, data: Dict) -> tuple[bool, str]:
        """验证需求数据"""
        try:
            # 检查必填字段
            for field in self.REQUIRED_FIELDS:
                if not data.get(field):
                    return False, f'缺少必填字段: {field}'
                
                # 检查字段值不为空
                if isinstance(data[field], str) and not data[field].strip():
                    return False, f'字段 {field} 不能为空'
            
            # 验证预算格式
            budget = data.get('budget_per_person')
            if budget and not isinstance(budget, str):
                return False, '预算格式不正确'
            
            # 验证状态
            status = data.get('status')
            if status and status not in self.STATUS_OPTIONS:
                return False, f'无效的状态值: {status}'
            
            return True, '验证通过'
            
        except Exception as e:
            logger.error(f'数据验证失败: {str(e)}')
            return False, f'数据验证失败: {str(e)}'
    
    def create(self, data: Dict) -> tuple[bool, str, Optional[Dict]]:
        """创建新需求"""
        try:
            # 验证数据
            is_valid, message = self.validate_data(data)
            if not is_valid:
                return False, message, None
            
            # 构建需求文档
            requirement = {
                'core_goal': data.get('core_goal', '').strip(),
                'target_audience': data.get('target_audience', '').strip(),
                'budget_per_person': data.get('budget_per_person', '').strip(),
                'focus_point': data.get('focus_point', '').strip(),
                'gift_preference': data.get('gift_preference', '').strip(),
                'specific_product': data.get('specific_product', '').strip(),
                'customer_preference': data.get('customer_preference', '').strip(),
                'customer_pain_points': data.get('customer_pain_points', '').strip(),
                'status': data.get('status', 'draft'),
                'createdAt': self.get_current_timestamp(),
                'lastModified': self.get_current_timestamp()
            }
            
            # 插入数据库
            result = self.collection.insert_one(requirement)
            
            if result.inserted_id:
                requirement['_id'] = result.inserted_id
                logger.info(f'需求创建成功: {result.inserted_id}')
                return True, '需求创建成功', self.to_dict(requirement)
            else:
                return False, '插入数据库失败', None
                
        except Exception as e:
            logger.error(f'创建需求失败: {str(e)}')
            return False, f'创建需求失败: {str(e)}', None
    
    def get_by_id(self, requirement_id: str) -> tuple[bool, str, Optional[Dict]]:
        """根据ID获取需求"""
        try:
            if not self.validate_object_id(requirement_id):
                return False, '无效的需求ID', None
            
            requirement = self.collection.find_one({'_id': ObjectId(requirement_id)})
            
            if requirement:
                return True, '获取成功', self.to_dict(requirement)
            else:
                return False, '需求不存在', None
                
        except Exception as e:
            logger.error(f'获取需求失败: {str(e)}')
            return False, f'获取需求失败: {str(e)}', None
    
    def update(self, requirement_id: str, data: Dict) -> tuple[bool, str, Optional[Dict]]:
        """更新需求"""
        try:
            if not self.validate_object_id(requirement_id):
                return False, '无效的需求ID', None
            
            # 检查需求是否存在
            existing = self.collection.find_one({'_id': ObjectId(requirement_id)})
            if not existing:
                return False, '需求不存在', None
            
            # 构建更新数据
            update_data = {
                'lastModified': self.get_current_timestamp()
            }
            
            # 处理允许更新的字段
            allowed_fields = self.REQUIRED_FIELDS + self.OPTIONAL_FIELDS + ['status']
            
            for field in allowed_fields:
                if field in data:
                    value = data[field]
                    if isinstance(value, str):
                        value = value.strip()
                    update_data[field] = value
            
            # 如果有必填字段更新，需要验证
            if any(field in data for field in self.REQUIRED_FIELDS):
                # 合并现有数据和更新数据进行验证
                merged_data = {**existing, **update_data}
                is_valid, message = self.validate_data(merged_data)
                if not is_valid:
                    return False, message, None
            
            # 更新数据库
            result = self.collection.update_one(
                {'_id': ObjectId(requirement_id)},
                {'$set': update_data}
            )
            
            if result.modified_count > 0 or result.matched_count > 0:
                # 获取更新后的文档
                updated_requirement = self.collection.find_one({'_id': ObjectId(requirement_id)})
                logger.info(f'需求更新成功: {requirement_id}')
                return True, '需求更新成功', self.to_dict(updated_requirement)
            else:
                return False, '更新失败', None
                
        except Exception as e:
            logger.error(f'更新需求失败: {str(e)}')
            return False, f'更新需求失败: {str(e)}', None
    
    def delete(self, requirement_id: str) -> tuple[bool, str]:
        """删除需求"""
        try:
            if not self.validate_object_id(requirement_id):
                return False, '无效的需求ID'
            
            # 检查需求是否存在
            existing = self.collection.find_one({'_id': ObjectId(requirement_id)})
            if not existing:
                return False, '需求不存在'
            
            # 删除需求
            result = self.collection.delete_one({'_id': ObjectId(requirement_id)})
            
            if result.deleted_count > 0:
                # 删除相关的方案内容
                self.db.solutions.delete_many({'requirementId': requirement_id})
                logger.info(f'需求删除成功: {requirement_id}')
                return True, '需求删除成功'
            else:
                return False, '删除失败'
                
        except Exception as e:
            logger.error(f'删除需求失败: {str(e)}')
            return False, f'删除需求失败: {str(e)}'
    
    def list(self, page: int = 1, limit: int = 10, status: Optional[str] = None) -> tuple[bool, str, Optional[Dict]]:
        """获取需求列表"""
        try:
            # 构建查询条件
            query = {}
            if status and status in self.STATUS_OPTIONS:
                query['status'] = status
            
            # 计算跳过的文档数
            skip = (page - 1) * limit
            
            # 查询数据库
            cursor = self.collection.find(query).sort('lastModified', -1).skip(skip).limit(limit)
            requirements = [self.to_dict(req) for req in cursor]
            
            # 获取总数
            total = self.collection.count_documents(query)
            
            result = {
                'requirements': requirements,
                'pagination': {
                    'page': page,
                    'limit': limit,
                    'total': total,
                    'pages': (total + limit - 1) // limit
                }
            }
            
            return True, '获取列表成功', result
            
        except Exception as e:
            logger.error(f'获取需求列表失败: {str(e)}')
            return False, f'获取需求列表失败: {str(e)}', None
    
    def get_summary(self, requirement_id: str) -> tuple[bool, str, Optional[Dict]]:
        """获取需求摘要信息"""
        try:
            success, message, requirement = self.get_by_id(requirement_id)
            if not success:
                return success, message, None
            
            summary = {
                'id': requirement['id'],
                'core_goal': requirement['core_goal'],
                'target_audience': requirement['target_audience'],
                'budget_per_person': requirement['budget_per_person'],
                'status': requirement['status'],
                'createdAt': requirement['createdAt'],
                'lastModified': requirement['lastModified']
            }
            
            return True, '获取摘要成功', summary
            
        except Exception as e:
            logger.error(f'获取需求摘要失败: {str(e)}')
            return False, f'获取需求摘要失败: {str(e)}', None

class SolutionModel(BaseModel):
    """方案内容模型"""
    
    # 必填字段
    REQUIRED_FIELDS = ['requirementId', 'content']
    
    # 来源选项
    SOURCE_OPTIONS = ['manual', 'doubao', 'kimi']
    
    def __init__(self, db):
        super().__init__(db.solutions)
        self.db = db
    
    def validate_data(self, data: Dict) -> tuple[bool, str]:
        """验证方案数据"""
        try:
            # 检查必填字段
            for field in self.REQUIRED_FIELDS:
                if not data.get(field):
                    return False, f'缺少必填字段: {field}'
            
            # 验证需求ID
            requirement_id = data.get('requirementId')
            if not self.validate_object_id(requirement_id):
                return False, '无效的需求ID'
            
            # 检查内容不为空
            content = data.get('content')
            if not content or not content.strip():
                return False, '方案内容不能为空'
            
            # 验证来源
            source = data.get('source')
            if source and source not in self.SOURCE_OPTIONS:
                return False, f'无效的来源值: {source}'
            
            return True, '验证通过'
            
        except Exception as e:
            logger.error(f'方案数据验证失败: {str(e)}')
            return False, f'数据验证失败: {str(e)}'
    
    def create(self, data: Dict) -> tuple[bool, str, Optional[Dict]]:
        """创建新方案"""
        try:
            # 验证数据
            is_valid, message = self.validate_data(data)
            if not is_valid:
                return False, message, None
            
            # 检查关联的需求是否存在
            requirement_id = data.get('requirementId')
            requirement = self.db.requirements.find_one({'_id': ObjectId(requirement_id)})
            if not requirement:
                return False, '关联的需求不存在', None
            
            # 获取当前版本号
            latest_solution = self.collection.find_one(
                {'requirementId': requirement_id},
                sort=[('version', -1)]
            )
            next_version = (latest_solution['version'] + 1) if latest_solution else 1
            
            # 构建方案文档
            solution = {
                'requirementId': requirement_id,
                'content': data.get('content').strip(),
                'source': data.get('source', 'manual'),
                'version': next_version,
                'isConfirmed': data.get('isConfirmed', False),
                'createdAt': self.get_current_timestamp(),
                'lastModified': self.get_current_timestamp()
            }
            
            # 插入数据库
            result = self.collection.insert_one(solution)
            
            if result.inserted_id:
                solution['_id'] = result.inserted_id
                logger.info(f'方案创建成功: {result.inserted_id}')
                return True, '方案创建成功', self.to_dict(solution)
            else:
                return False, '插入数据库失败', None
                
        except Exception as e:
            logger.error(f'创建方案失败: {str(e)}')
            return False, f'创建方案失败: {str(e)}', None
    
    def get_history(self, requirement_id: str) -> tuple[bool, str, Optional[List[Dict]]]:
        """获取方案历史记录"""
        try:
            if not self.validate_object_id(requirement_id):
                return False, '无效的需求ID', None
            
            # 查询方案历史
            cursor = self.collection.find({'requirementId': requirement_id}).sort('createdAt', -1)
            solutions = [self.to_dict(solution) for solution in cursor]
            
            return True, '获取历史成功', solutions
            
        except Exception as e:
            logger.error(f'获取方案历史失败: {str(e)}')
            return False, f'获取方案历史失败: {str(e)}', None
    
    def get_latest(self, requirement_id: str) -> tuple[bool, str, Optional[Dict]]:
        """获取最新方案"""
        try:
            if not self.validate_object_id(requirement_id):
                return False, '无效的需求ID', None
            
            solution = self.collection.find_one(
                {'requirementId': requirement_id},
                sort=[('createdAt', -1)]
            )
            
            if solution:
                return True, '获取最新方案成功', self.to_dict(solution)
            else:
                return False, '没有找到方案', None
                
        except Exception as e:
            logger.error(f'获取最新方案失败: {str(e)}')
            return False, f'获取最新方案失败: {str(e)}', None
    
    def confirm_solution(self, solution_id: str) -> tuple[bool, str, Optional[Dict]]:
        """确认方案"""
        try:
            if not self.validate_object_id(solution_id):
                return False, '无效的方案ID', None
            
            # 更新确认状态
            result = self.collection.update_one(
                {'_id': ObjectId(solution_id)},
                {
                    '$set': {
                        'isConfirmed': True,
                        'confirmedAt': self.get_current_timestamp(),
                        'lastModified': self.get_current_timestamp()
                    }
                }
            )
            
            if result.modified_count > 0:
                # 获取更新后的文档
                updated_solution = self.collection.find_one({'_id': ObjectId(solution_id)})
                logger.info(f'方案确认成功: {solution_id}')
                return True, '方案确认成功', self.to_dict(updated_solution)
            else:
                return False, '确认失败', None
                
        except Exception as e:
            logger.error(f'确认方案失败: {str(e)}')
            return False, f'确认方案失败: {str(e)}', None
    
    def delete_by_requirement(self, requirement_id: str) -> tuple[bool, str]:
        """删除指定需求的所有方案"""
        try:
            if not self.validate_object_id(requirement_id):
                return False, '无效的需求ID'
            
            result = self.collection.delete_many({'requirementId': requirement_id})
            
            logger.info(f'删除需求 {requirement_id} 的 {result.deleted_count} 个方案')
            return True, f'删除了 {result.deleted_count} 个方案'
            
        except Exception as e:
            logger.error(f'删除方案失败: {str(e)}')
            return False, f'删除方案失败: {str(e)}'
    
    def get_statistics(self, requirement_id: str) -> tuple[bool, str, Optional[Dict]]:
        """获取方案统计信息"""
        try:
            if not self.validate_object_id(requirement_id):
                return False, '无效的需求ID', None
            
            # 聚合统计
            pipeline = [
                {'$match': {'requirementId': requirement_id}},
                {
                    '$group': {
                        '_id': None,
                        'total': {'$sum': 1},
                        'confirmed': {
                            '$sum': {
                                '$cond': [{'$eq': ['$isConfirmed', True]}, 1, 0]
                            }
                        },
                        'sources': {'$push': '$source'},
                        'latest_version': {'$max': '$version'}
                    }
                }
            ]
            
            result = list(self.collection.aggregate(pipeline))
            
            if result:
                stats = result[0]
                # 统计来源分布
                source_count = {}
                for source in stats['sources']:
                    source_count[source] = source_count.get(source, 0) + 1
                
                statistics = {
                    'total': stats['total'],
                    'confirmed': stats['confirmed'],
                    'latest_version': stats['latest_version'],
                    'source_distribution': source_count
                }
            else:
                statistics = {
                    'total': 0,
                    'confirmed': 0,
                    'latest_version': 0,
                    'source_distribution': {}
                }
            
            return True, '获取统计成功', statistics
            
        except Exception as e:
            logger.error(f'获取方案统计失败: {str(e)}')
            return False, f'获取方案统计失败: {str(e)}', None